from PyQt4 import QtGui, QtCore
import os, random, gCity, gMap, gUnit
from gSystem import findRandomAppend
from gJson import loadString, loadInteger, loadObject, loadArray, loadCoordinates

class GameSession(object):
    
    def __init__(self):
        self.turn = 0
        self.turnComplete = False
        self.unitsByLoc = {}
        self.map = None
        self.factions = {}
        self.units = {}
        self.cities = {}
        self.citiesByLoc = {}
        
    def generateStartingStuff(self):
        for faction in self.factions.values():
            core = self.getFreeCore()
            self.addCity(gCity.City("Test City", core, "city.png", 1000))
            self.addUnit(gUnit.Unit(self.getFreeAdjacent(core), "ninja.png", self, [gUnit.Troop(prof="Ninja"), gUnit.Troop(prof="Warriors")], faction._name))
            
    def generateMap(self):
        self.map = gMap.Map()
        
    def loadMap(self, mappe):
        self.map = gMap.Map.load(mappe)
        
    def addFaction(self, uza, faction):
        self.factions[uza] = faction
        
    def getFactions(self):
        return self.factions.values()
        
    def getNumberOfFactions(self):
        return len(self.factions)

    def addCity(self, city, ID=None):
        if self.citiesByLoc.has_key(city.getLoc()):
            return
        if ID is not None:
            self.cities[ID] = city
            self.cities[ID].setID(ID)
            self.citiesByLoc[city.getLoc()] = city
            return
        newID = self._findUniqueID()
        self.cities[newID] = city
        self.cities[newID].setID(newID)
        self.citiesByLoc[city.getLoc()] = city
    
    def addUnit(self, unit, ID=None):
        if self.unitsByLoc.has_key(unit.getLoc()):
            pass #Combine units or whatevers
        if ID is not None:
            self.units[ID] = unit
            self.units[ID].setID(ID)
            self.unitsByLoc[unit.getLoc()] = unit
            return
        newID = self._findUniqueID()
        self.units[newID] = unit
        self.units[newID].setID(newID)
        self.unitsByLoc[unit.getLoc()] = unit
        
    def moveUnit(self, unit, targ):
        del self.unitsByLoc[unit.getLoc()]
        unit.changePosition(targ)
        self.unitsByLoc[unit.getLoc()] = unit
        
    def armyMoveOrder(self, ID, targ):
        self.units[ID].orderMove(targ, self.map.getTileType(targ))
        
    def checkCanMove(self, ID, targ):
        return self.units[ID].canMove(targ, self.map.getTileType(targ))
    
    def getFactionByHandle(self, handle):
        return self.factions[handle]
        
    def getOwnerByID(self, ID):
        own = self.getUnitFactionByID(ID)
        for player, fact in self.factions.items():
            if fact._name == own:
                return player
    
    def getUnitFactionByID(self, ID):
        return self.units[ID]._owner
        
    def _findUniqueID(self):
        id = findRandomAppend()
        while id in self.units:
            id += findRandomAppend()
        return id
    
    def getTileStuff(self, loc):
        if self.unitsByLoc.has_key(loc):
            return (self.map.getTileType(loc), self.unitsByLoc[loc])
        elif self.citiesByLoc.has_key(loc):
            return (self.map.getTileType(loc), self.citiesByLoc[loc])
        else:
            return (self.map.getTileType(loc))
        
    def dump(self):
        return dict()
    
    def dumpUnits(self):
        return dict([(unit.ID, unit.dump()) for unit in self.units.values()])

    def dumpCities(self):
        return dict([(city.ID, city.dump()) for city in self.cities.values()])
    
    def advanceTurn(self):
        for unit in self.units.values():
            unit.advanceTurn()
            
    def getFreeCore(self):
        for x in range(0, 100):
            tmp = self.map.randomCore()
            if not self.unitsByLoc.has_key(tmp):
                return tmp
        return (0, 0)

    def getFreeAdjacent(self, loc):
        return self.map.getFreeAdjacent(loc)

    def loadCities(self, obj):
        for ID, city in obj.items():
            loaded = gCity.City.load(city, self)
            self.addCity(loaded, ID)
    
    def loadUnits(self, obj):
        for ID, unit in obj.items():
            loaded = gUnit.Unit.load(unit, self)
            self.addUnit(loaded, ID)
    
    @staticmethod
    def load(obj):
        sess = GameSession()
            
        return sess
